<?php
/*
 * @Author: your name
 * @Date: 2020-05-25 10:08:14
 * @LastEditTime: 2020-05-26 16:29:41
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /v3/application/adminapiv3/service/userManage/UserGroupService.php
 */ 
namespace app\adminapiv3\service\userManage;

use app\adminapiv3\service\Base;
use app\adminapiv3\service\ServerAuth;
use think\Db;

class UserGroupService extends Base
{
    public $module;//授权模块
    /**
     * @name: 列表
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-05-25 10:08:59
     */
    function list ()
    {
        $user = $this->getUserInfo();

        $list = db('server_user_group_relation')->alias('sr')
            ->join('server_user_group sg', 'sg.id = sr.group_id')
            ->where('f_group_id', $user['user_group_id'])
            ->order('level','asc')
            ->field('sg.id, sg.name, sg.upper_id, sg.level')
            ->select();

        foreach ($list as $k => $v){
            $list[$k]['is_self'] = $user['user_group_level'] == $v['level'] ? 1 : 0;
            $list[$k]['is_admin'] = $v['id'] == 1 ? 1 : 0;

        }
        return $list;
    }



    /**
     * @name: 添加
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-05-26 11:03:02
     */
    function add ($input) 
    {

        $user = $this->getUserInfo();

        $userGroupId = $user['user_group_id'];
        $groupLevel = $user['user_group_level'];

        //1. 验证名称是否重复
        $nameCount = db('server_user_group')->where('name', $input['name'])->count();


        if($nameCount != 0){
            returnErrJson($this->CODE_FAIL, '已存在该用户组');
        }

        //2. 验证授权个数,时间
        $this->checkAuthData($input['module'], $userGroupId);

        //3. 添加用户组
        $nowGroupId = db('server_user_group')->insertGetId([
            'name' => $input['name'],
            'company' => empty($input['company']) ? '' : $input['company'],
            'upper_id' => $userGroupId,
            'level' => $groupLevel + 1,
            'ctime' => time(),
            'bind_key' => md5(microtime(true)),
        ]);

        //4.添加关系 查询当前用户所有上级
        $fGroupId = db('server_user_group_relation')->where('group_id', $userGroupId)->field('f_group_id')->select();

        foreach ($fGroupId as $k => $v){
            $v['group_id'] = $nowGroupId;
            $fGroupId[$k] = $v;
        }

        $self = array(['f_group_id' => $nowGroupId, 'group_id' => $nowGroupId]);
        $addData = array_merge($fGroupId, $self);

        db('server_user_group_relation')->insertAll($addData);

        //5. 修改当前用户组授权数量
        $this->AuthDataDandle($input['module'], $nowGroupId, $userGroupId);

        return true;
    }

    /**
     * @name: 删除
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-05-26 13:29:17
     */
    function delete ($groupId)
    {
        $user = $this->getUserInfo();
        
        $fGroupId = $user['user_group_id'];

        //1. 验证是否有越级修改
        $nowGroupInfo = db('server_user_group')->where('id', $groupId)->find();

        $this->checkLevel($nowGroupInfo['level'], $user['user_group_level']);




        //验证此用户组是否有组员
        $userCount = db('server_user')->where('user_group_id', $groupId)->count();
        if($userCount != 0){
            returnErrJson($this->CODE_FAIL, '此用户组里有用户,暂不能删除');
        }

        //验证此用户组是否有下级用户组
        $groupCount = db('server_user_group')->where('upper_id', $groupId)->count();
        if($groupCount != 0){
            returnErrJson($this->CODE_FAIL, '此用户组里有下级用户组,暂不能删除');
        }

        //2. 验证是否正在有使用的授权
        $used = db('server_user_group_module')->where('group_id', $groupId)->sum('used');

        if($used > 0){
            returnErrJson($this->CODE_FAIL, '此用户组里有部分授权正在使用,暂不能删除');
        }

        //删除用户组数据
        db('server_user_group')->where('id', $groupId)->where('upper_id', $fGroupId)->delete();

        //删除用户组关系数据
        db('server_user_group_relation')->where('group_id', $groupId)->delete();

        //查询出各个模块授权的数量 修改上级授权数量 删除本用户组授权
        $moduleArr = db('server_user_group_module')->where('group_id', $groupId)->select();
        foreach ($moduleArr as $k => $v){
            db('server_user_group_module')
                ->where('group_id', $fGroupId)
                ->where('module_id', $v['module_id'])
                ->setDec('used', $v['total']);
        }
        db('server_user_group_module')->where('group_id', $groupId)->delete();
    }

    /**
     * @name 详细信息
     * @param $userGroupId
     * @return array|null|\PDOStatement|string|\think\Model
     * @author wx
     * @date 2020/7/22 17:28
     */
    function info($userGroupId)
    {
        $info = db('server_user_group')->field('id, name, company')->where('id', $userGroupId)->find();

        //查询模块信息
        $info['module'] = db('server_user_group_module')->where('group_id', $userGroupId)->select();

        return $info;
    }

    /**
     * @name: 修改
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-05-26 13:35:46
     */
    function modify ($groupId, $updateData)
    {
        $user = $this->getUserInfo();

        $userGroupId = $user['user_group_id'];

        //1. 验证是否有越级修改
        $nowGroupInfo = db('server_user_group')->where('id', $groupId)->find();
        $this->checkLevel($nowGroupInfo['level'], $user['user_group_level']);


        //2. 验证名称重复
        $nameCount = db('server_user_group')
            ->where('name', $updateData['name'])
            ->where('id', '<>', $groupId)
            ->count();

        if($nameCount != 0){
            returnErrJson($this->CODE_FAIL, '已存在该用户组');
        }

        $this->checkAuthData($updateData['module'], $userGroupId, 'modify', $groupId);


        //3. 处理数据
        db('server_user_group')->where('id', $groupId)->update([
            'name' => $updateData['name'], 'company' => $updateData['company']
        ]);
        $this->AuthDataDandle($updateData['module'], $groupId, $userGroupId);

    }

    /**
     * @name 检验是否越级操作
     * @param $nowLevel 当前操作用户组等级
     * @param $nowUserLevel当前登录用户等级
     * @author wx
     * @date 2020/7/20 10:53
     */
    function checkLevel($nowLevel , $nowUserLevel)
    {
        if($nowLevel == $nowUserLevel){
            returnErrJson($this->CODE_FAIL, '你不能对自己所在用户组做此操作');
        }
        if($nowUserLevel + 1 != $nowLevel){
            returnErrJson($this->CODE_FAIL, '你不能对当前用户组做此操作');
        }
    }

    /**
     * @name 验证授权模块数据
     * @param $module
     * @author wx
     * @date 2020/11/11 13:42
     */
    public function checkAuthData($module, $fGroupId, $type = 'add', $nowGroupId = 0)
    {
        if (!is_array($module)) {
            returnErrJson($this->CODE_FAIL, '授权模块数据错误');
        }



        foreach ($module as $k => $v){


            if(!$v['module_id'] || !$v['total'] || !$v['etime']){
                returnErrJson($this->CODE_FAIL, '参数错误');
            }

            $moduleInfo = db('server_auth_module')->where('id', $v['module_id'])->find();


            if(!$moduleInfo){
                returnErrJson($this->CODE_FAIL, '授权模块错误');
            }

            $groupAuthInfo = db('server_user_group_module')
                ->where('group_id', $fGroupId)
                ->where('module_id', $v['module_id'])->find();

            //判断上级用户组时候有当前模块授权的权限
            if(!$groupAuthInfo){
                returnErrJson($this->CODE_FAIL, '您的用户组没有授权'.$moduleInfo['module_name'].'模块');
            }

            //最大可用数量 = total - used
            $max = $groupAuthInfo['total'] - $groupAuthInfo['used'];
            $min = 1;

            if($type == 'modify'){
                $groupAuthInfo = db('server_user_group_module')
                    ->where('group_id', $nowGroupId)
                    ->where('module_id', $v['module_id'])->find();

                if(isset($groupAuthInfo['used'])){
                    $min = $groupAuthInfo['used'] < 1 ? 1 : $groupAuthInfo['used'];
                }
            }

            //授权数量判断
            if ($v['total'] > $max || $v['total'] < $min) {

                if($max < $min){
                    returnErrJson($this->CODE_FAIL, $moduleInfo['module_name'].'可用授权数量不足');
                }
                returnErrJson($this->CODE_FAIL, $moduleInfo['module_name'].'授权数量必须在'.$min.'与'.$max.'之间');
            }

            //授权时间
            if($groupAuthInfo['etime'] != 0 && $v['etime'] > $groupAuthInfo['etime']){
                returnErrJson($this->CODE_FAIL, $moduleInfo['module_name'].'最大授权时间为'.date('Y-m-d', $groupAuthInfo['etime']));
            }

            $v['module_key'] = $moduleInfo['module_key'];
            $this->module[$k] = $v;
        }

    }

    /**
     * @name 处理模块数据
     * @param $module 模块信息
     * @param $nowGroupId 当前需要修改的用户组ID
     * @param $fGoupId 上级用户组ID
     * @author wx
     * @date 2020/11/12 9:50
     */
    public function AuthDataDandle($module, $nowGroupId, $fGoupId)
    {
        foreach ($this->module as $k => $v){

            //验证通过, 修改授权状态
            $authServer = new ServerAuth();
            $systemTime = $authServer->getSystemTime();

            $updateNum = 0;
            if($v['etime'] >= $systemTime){

                //成功开启当前模块的主机数量
                $successOpenNum = Db::name('host h')
                    ->join('host_module_relation hmr', 'h.id = hmr.host_id')
                    ->where('group_id', $nowGroupId)
                    ->where($v['module_key'], 1)
                    ->count();

                //需要开启的当前模块的数量
                $needOpenNum = $v['total'] - $successOpenNum;

                if($needOpenNum > 0){
                    //根据主机id从小到大开启当前模块
                    $hostIdArr = Db::name('host_module_relation hmr')
                        ->join('host h', 'h.id = hmr.host_id')
                        ->where($v['module_key'], 0)
                        ->where('group_id', $nowGroupId)
                        ->order('host_id asc')
                        ->limit($needOpenNum)
                        ->column('host_id');

                    $updateNum = Db::name('host_module_relation')->whereIn('host_id', $hostIdArr)->update([$v['module_key'] => 1]);
                }

            }

            $where = [
                'group_id' => $nowGroupId,
                'module_id' => $v['module_id']
            ];
            //添加本用户组数据
            $nowInfo = db('server_user_group_module')->where($where)->find();

            if($nowInfo){//修改

                $groupAuthData = [
                    'total' => $v['total'],
                    'used' => Db::raw("used + {$updateNum}"),
                    'etime' => $v['etime'],
                ];
                //处理本用户组数据
                db('server_user_group_module')->where($where)->update($groupAuthData);

                $change = $v['total'] - $nowInfo['total'];//处理变化量

            }else{//添加

                $addData['group_id'] = $nowGroupId;
                $addData['module_id'] = $v['module_id'];
                $addData['total'] = $v['total'];
                $addData['used'] = $updateNum;
                $addData['etime'] = $v['etime'];


                db('server_user_group_module')->insert($addData);

                $change = $v['total'];
            }

            //处理上级用户组已经使用数据
            db('server_user_group_module')
                ->where('group_id', $fGoupId)
                ->where('module_id', $v['module_id'])
                ->setInc('used', $change);
        }
    }

    /**
     * @name 根据当前用户来返回可以授权模块
     * @author wx
     * @date 2020/11/12 10:30
     */
    public function module()
    {
        //获取当前用户信息
        $user = $this->getUserInfo();

        //2. 查找数据
        $data = db('server_auth_module sam')
            ->join('server_user_group_module sugm', 'sam.id = sugm.module_id')
            ->where('sugm.group_id', $user['user_group_id'])
            ->field('sugm.module_id, sam.module_name, total, used, sugm.etime')
            ->select();

        return $data;
    }


}